home *** CD-ROM | disk | FTP | other *** search
- /* (c) 1990 S.Hawtin.
- Permission is granted to copy this file provided
- 1) It is not used for commercial gain
- 2) This notice is included in all copies
- 3) Altered copies are marked as such
-
- No liability is accepted for the contents of the file.
-
- */
-
- /* A program that will dump out executable code */
-
- #include <stdio.h>
- #include <stdarg.h>
-
- int with_data = TRUE;
- int with_code = TRUE;
- int with_reloc = TRUE;
- int with_code_data = FALSE;
- char *data_name = NULL;
- FILE *in;
-
- #define NAME_LEN 128
- char name[NAME_LEN];
-
- quit()
- {/* Close down the files and exit */
- fclose(in);
- exit(0);
- }
-
- void
- my_fread(buff,num,fptr)
- char *buff;
- int num;
- FILE *fptr;
- {/* Read some bytes into a buffer */
- int i;
-
- for(i=0;i<num;i++)
- {/* The file should be buffered anyway */
- buff[i] = fgetc(fptr);
- if(feof(fptr))
- quit();
- }
- }
-
- now_printing = TRUE;
-
- void
- my_printf(str,args)
- char *str;
- {/* Do a printf, by putting it here we can do things like turn it off
- and duplicate into another file */
- va_list va_args;
-
- va_start(va_args,str);
- if(now_printing)
- vprintf(str,va_args);
- va_end(va_args);
- }
-
- /* Because of a new bug in the optimiser these static variables must
- be left outside the function */
-
- static char *read_buffer;
- static int read_buf_len = 0;
-
- char *
- read_name(fptr,symb)
- FILE *fptr;
- int symb;
- {/* Read the next name, preceeded by its length */
- long length;
-
- my_fread(&length,sizeof(long),in);
- if(symb)
- length &= 0xffffff;
- if(length*sizeof(long) > read_buf_len-1)
- {if(read_buffer)
- free(read_buffer);
- read_buffer = malloc(length*sizeof(long) + 1);
- if(read_buffer==NULL)
- {my_printf("malloc failed\n");
- exit(20);
- }
- read_buf_len = length*sizeof(long) + 1;
- }
-
- my_fread(read_buffer,length*sizeof(long),in);
- read_buffer[length*sizeof(long)] = '\0';
- return(read_buffer);
- }
-
- void
- dump_data(in)
- FILE *in;
- {/* Dump out some data */
- unsigned char line[16];
- long length;
- int line_num,i,old_print;
-
- if(!with_data)
- {
- old_print = now_printing;
- now_printing = FALSE;
- }
-
- my_fread(&length,sizeof(long),in);
- line_num = 0;
- while(line_num < length/4)
- {/* Full line */
- my_fread(line,16,in);
- my_printf(" %05x:",line_num*16);
-
- for(i=0;i<16;i++)
- {
- if(i%4 == 0)
- my_printf(" ");
- if(i%2 == 0)
- my_printf(" ");
- my_printf("%02x",line[i]);
- }
- my_printf(" ");
- for(i=0;i<16;i++)
- {
- my_printf("%c",(line[i]>=0x20 && line[i]<0x80)?line[i]:'.');
- }
- my_printf("\n");
- line_num++;
- }
-
- /* Final line */
- length -= line_num*4;
- if(0 != length)
- {/* We have a partial line */
- my_fread(line,length*4,in);
- my_printf(" %05x:",line_num*16);
-
- for(i=0;i<16;i++)
- {
- if(i%4 == 0)
- my_printf(" ");
- if(i%2 == 0)
- my_printf(" ");
- if(length*4<=i)
- my_printf(" ");
- else
- my_printf("%02x",line[i]);
- }
- my_printf(" ");
- for(i=0;i<length*4;i++)
- {
- my_printf("%c",(line[i]>=0x20 && line[i]<0x80)?line[i]:'.');
- }
- my_printf("\n");
- }
- if(!with_data)
- {
- now_printing = old_print;
- }
- }
-
- void
- dump_code(in)
- FILE *in;
- {/* Dump executable code */
- int old_print;
-
- if (!with_code)
- {old_print = now_printing;
- now_printing = FALSE;
- }
- if(with_code_data)
- dump_data(in);
- else
- {/* Dump the code as real code, not done yet */
- long length;
-
- my_fread(&length,sizeof(long),in);
- disass(length,in);
- }
- if(!with_code)
- {
- now_printing = old_print;
- }
- }
-
- void
- dump_reloc(num,in)
- long num;
- FILE *in;
- {/* Dump relocations on multiple lines */
- int i;
- long val;
- int old_print;
-
- i=0;
- if(num>4)
- {
- if (!with_reloc)
- {old_print = now_printing;
- now_printing = FALSE;
- }
- while(num>0)
- {if (i%5 == 0)
- my_printf("\n ");
- my_fread(&val,sizeof(long),in);
- my_printf(" %08x",val);
- --num;
- ++i;
- }
- if (!with_reloc)
- {
- now_printing = old_print;
- }
- }
- else
- while(num>0)
- {my_fread(&val,sizeof(long),in);
- my_printf(" %08x",val);
- --num;
- }
- my_printf("\n");
- }
-
- void
- dump_reloc32(in)
- FILE *in;
- {/* Inter hunk relocation information */
- long num,val;
-
- my_fread(&num,sizeof(long),in);
- while(num!=0)
- {/* Dump this relocation */
- my_fread(&val,sizeof(long),in);
- my_printf(" Hunk %2ld @ ",val);
- dump_reloc(num,in);
- my_fread(&num,sizeof(long),in);
- }
- }
-
- void
- dump_ext(in)
- FILE *in;
- {/* Dump external symbol table */
- int next;
- long num;
-
- next = getc(in);
- ungetc(next,in);
- while(next!=0)
- {/* Dump out this symbol */
- my_printf(" \"%s\" ",read_name(in,TRUE));
- my_fread(&num,sizeof(long),in);
- switch(next)
- {
- case 0x02:
- my_printf("Abs Val ");
- case 0x01:
- my_printf(" = %08x\n",num);
- break;
- case 0x83:
- my_printf(" 16 bit ");
- case 0x81:
- my_printf(" @ ");
- dump_reloc(num,in);
- break;
- default:
- my_printf("### ERROR ### Ext code of %02x\n",next);
- }
-
- next = getc(in);
- ungetc(next,in);
- }
- my_fread(&num,sizeof(long),in);
- if(num!=0)
- my_printf("### ERROR ### End of Ext %08x\n",num);
- }
-
- void
- dump_symbol(in)
- FILE *in;
- {/* Dump symbol entries */
- char *name;
- long val;
-
- do {
- name = read_name(in,TRUE);
- if(*name)
- {my_fread(&val,sizeof(long),in);
- my_printf(" \"%s\" = %08x\n",name,val);
- }
- } while(*name);
- }
-
- void
- dump_header(in)
- FILE *in;
- {/* Dump the hunk header */
- long val1,val2,val3,val4;
-
- my_fread(&val1,sizeof(long),in);
- my_fread(&val2,sizeof(long),in);
- my_fread(&val3,sizeof(long),in);
- my_fread(&val4,sizeof(long),in);
- /* The first seems to always be 0 */
- my_printf(" %ld %ld %ld %ld ",val1,val2,val3,val4);
- dump_reloc(val2,in);
- }
-
- void
- doopts(argc,argv)
- int argc;
- char **argv;
- {/* Get the command line options */
- int i;
-
- for(i=1;i<argc;i++)
- {if(argv[i][0] == '-')
- {
- switch(argv[i][1])
- {
- case 'h': case 'H':
- /* Ignore the actual data */
- with_data = FALSE;
- with_code = FALSE;
- with_reloc = FALSE;
- break;
- case 'L': case 'l':
- with_code_data = TRUE;
- break;
- default:
- /* Tell the user the real set of options */
- goto out_options;
- }
- }
- else if(data_name==NULL)
- {/* Data file name */
- data_name = argv[i];
- }
- else
- {
- out_options:
- my_printf("Options are\n\n");
- my_printf(" -h\n");
- my_printf(" -l\n");
- my_printf(" <objectfile>\n");
- exit(20);
- }
- }
- }
-
- void
- main(argc,argv)
- int argc;
- char **argv;
- {/* dump out what the contents are */
- int count;
- long len;
-
- doopts(argc,argv);
-
- if(data_name==NULL)
- {printf("Need file name to read\n");
- exit(20);
- }
-
- in = fopen(data_name,"r");
- if(in==NULL)
- {printf("Cannot open \"%s\"\n",data_name);
- exit(20);
- }
-
- /* So we can now get down to the serious buisness of scanning the
- data file */
-
- count = 0;
- while(TRUE)
- {/* Keep scanning until we have an end of file or we find
- a final marker */
- long flag;
-
- my_fread(&flag,4,in);
- switch(flag)
- {case 0x3e7:
- my_printf("Hunk PU Name \"%s\"\n",read_name(in,FALSE));
- break;
- case 0x3e8:
- my_printf("Hunk Name \"%s\"\n",read_name(in,FALSE));
- break;
- case 0x3e9:
- my_printf("Hunk Code Public\n");
- dump_code(in);
- break;
- case 0x3ea:
- my_printf("Hunk Data Public\n");
- dump_data(in);
- break;
- case 0x3eb:
- my_fread(&len,sizeof(long),in);
- my_printf("Hunk BSS Public %x\n",len*4);
- break;
- case 0x3ec:
- my_printf("Hunk Reloc 32\n");
- dump_reloc32(in);
- break;
- case 0x3ef:
- my_printf("Hunk Ext\n");
- dump_ext(in);
- break;
- case 0x3f0:
- my_printf("Hunk Symbol\n");
- dump_symbol(in);
- break;
- case 0x3f2:
- my_printf("Hunk End\n");
- break;
- case 0x3f3:
- my_printf("Hunk Header\n");
- dump_header(in);
- break;
- default:
- count++;
- my_printf("%08x ",flag);
- if((count%4) == 0)
- my_printf("\n");
- }
- }
- }
-